package utils

import (
	"bufio"
	"fmt"
	"io"
	"k8s.io/klog/v2"
	"os/exec"
	"sync"
)

func RunSSHCommand(comm string, args ...string) (shouldRetry bool, err error) {
	// 获取执行命令
	cmd := exec.Command(comm, args...)

	// 创建管道用于捕获命令的标准输出和标准错误
	stdoutPipe, err := cmd.StdoutPipe()
	if err != nil {
		return false, fmt.Errorf("failed to create stdout pipe: %v", err)
	}
	stderrPipe, err := cmd.StderrPipe()
	if err != nil {
		return false, fmt.Errorf("failed to create stderr pipe: %v", err)
	}

	// 开始执行命令
	if err = cmd.Start(); err != nil {
		return false, fmt.Errorf("failed to start command: %v", err)
	}

	// 读取标准输出和标准错误，并检查是否需要重试
	shouldRetryCh := make(chan bool)
	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		shouldRetryCh <- readOutput(stdoutPipe)
	}()

	go func() {
		defer wg.Done()
		shouldRetryCh <- readOutput(stderrPipe)
	}()

	go func() {
		wg.Wait()
		close(shouldRetryCh)
	}()

	// 检查是否需要重试
	for shouldRetry = range shouldRetryCh {
		if shouldRetry {
			// 如果其中一个goroutine发现需要重试，则立即返回
			return true, nil
		}
	}

	// 等待命令执行完毕
	if err = cmd.Wait(); err != nil {
		return false, fmt.Errorf("Command execution failed: %v", err)
	}

	return false, nil
}

func readOutput(pipe io.Reader) bool {
	reader := bufio.NewReader(pipe)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			klog.Errorf("Failed to read output: %v\n", err)
			return true // 如果发生错误，可能需要重试
		}
		fmt.Print(line) // 输出命令的标准输出或标准错误内容
		// 如果读取到特定错误信息，可以在此处进行处理，返回true表示需要重试
	}
	return false // 没有发现需要重试的情况
}
